﻿using System;
using System.Text;
using System.Web.Mvc;
using BoneSystem.Business;
using BoneSystem.Business.Entity;
using BoneSystem.Business.Enum;
using BoneSystem.Models;

namespace BoneSystem.Controllers
{
    public abstract class CadastroBaseController<T> : Controller where T : class, new()
    {
        /// <summary>
        /// Página inicial do cadastro.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public virtual ActionResult Index()
        {
            return View(RepositoryBase<T>.GetListAtivos());
            }

        public virtual ActionResult LoadPartialView()
        {
            return View("CadastroPartial", new T());
        }
        public virtual ActionResult New()
        {
            return View("Cadastro", new T());
        }
        [HttpPost]
        public virtual JsonResult NewJson()
        {
            try
            {
                return Json(JsonResultModel<T>.SendDataReturn(new T()));
            }
            catch (Exception ex)
            {
                return Json(JsonResultModel<T>.Fail(MontaMensagemErroValidacao()));
            }
            
        }

        /// <summary>
        /// Action que carrega um objeto. Caso o valor do parametro seja '0' cria um novo objeto.
        /// </summary>
        /// <param name="id">Identificador do objeto(0 para novo)</param>
        /// <returns>View de cadastro com o tipo carregado.</returns>
        [HttpGet]
        public virtual ActionResult Get(int id)
        {
            var propBase = PropertiesBaseRepository.GetById(id);
            T entity = propBase != null ? RepositoryBase<T>.GetById(id) : new T();
            return View("Cadastro", entity);
        }
        /// <summary>
        /// Action que carrega um objeto. Caso o valor do parametro seja '0' cria um novo objeto.
        /// </summary>
        /// <param name="id">Identificador do objeto(0 para novo)</param>
        /// <returns>View de cadastro com o tipo carregado.</returns>
        [HttpPost]
        public virtual JsonResult GetJson(int id)
        {
            try
            {
                var propBase = PropertiesBaseRepository.GetById(id);
                T entity;
                if (propBase != null)
                {
                    entity = RepositoryBase<T>.GetById(id);
                }
                else
                {
                    entity = new T();
                }
                return Json(JsonResultModel<T>.SendDataReturn(entity));
            }
            catch (Exception ex)
            {
                return Json(JsonResultModel<T>.Fail(MontaMensagemErroValidacao()));
            }
            
        }

        /// <summary>
        /// Action que salva um objeto no banco de dados.
        /// </summary>
        /// <param name="model">Modelo do objeto enviado pelo cliente para salvar no banco de dados</param>
        /// <returns>Retorna um valor informando se a operação foi bem sussedida.</returns>
        [HttpPost]
        public virtual ActionResult Save(T model)
        {
            if (ModelState.IsValid)
            {
                RepositoryBase<T>.Save(model);
            }

            return View("Cadastro",model);
        }

        /// <summary>
        /// Action que salva um objeto no banco de dados.
        /// </summary>
        /// <param name="entity">Modelo do objeto enviado pelo cliente para salvar no banco de dados</param>
        /// <returns>Retorna um valor informando se a operação foi bem sussedida.</returns>
        [HttpPost]
        public virtual JsonResult SaveJson(T entity)
        {
            try
            {
                entity = LoadReferences(entity);

                ModelState.Clear();
                TryValidateModel(entity);

                if (ModelState.IsValid)
                {
                    RepositoryBase<T>.Save(entity);
                    return Json(JsonResultModel<T>.SendDataReturn(entity, true, "Item salvo com sucesso"));
                }
                else
                {
                    return Json(JsonResultModel<T>.Fail(MontaMensagemErroValidacao()));
                }
                
            }
            catch (Exception ex)
            {
                return Json(JsonResultModel<T>.Fail(ex.Message));
            }

            
        }

        private string MontaMensagemErroValidacao()
        {
            var result = new StringBuilder("");
            foreach (var error in ModelState.Values)
            {
                foreach (var error1 in error.Errors)
                {
                    result.Append(error1.ErrorMessage + "\n");
                }
                
            }
            return result.ToString();
        }

        /// <summary>
        /// Método que exclui um objeto no banco de dados.
        /// </summary>
        /// <param name="id">Identificador do objeto para exclusão.</param>
        /// <returns>Retorna um valor informando se a exclusão foi bem sucedida.</returns>
        [HttpPost]
        public virtual JsonResult Delete(int id)
        {
            try
            {
                var entity = PropertiesBaseRepository.GetById(id);
                entity.Status = StatusEnum.Excluido;
                PropertiesBaseRepository.Save(entity);
                return Json(new JsonResultModel<T>()
                {
                    DataObject = new T(),
                    Message = "Exclusão efetuada com sucesso."
                });
            }
            catch (Exception ex)
            {
                return Json(JsonResultModel<T>.Fail(MontaMensagemErroValidacao()));
            }
        }

        /// <summary>
        /// Método que exclui um objeto no banco de dados.
        /// </summary>
        /// <param name="id">Identificador do objeto para exclusão.</param>
        /// <returns>Retorna um valor informando se a exclusão foi bem sucedida.</returns>
        [HttpPost]
        public virtual JsonResult DeleteJson(int id)
        {
            try
            {
                var entity = PropertiesBaseRepository.GetById(id);
                entity.Status = StatusEnum.Excluido;
                PropertiesBaseRepository.Save(entity);
                return Json(new JsonResultModel<T>()
                {
                    DataObject = new T(),
                    Message = "Exclusão efetuada com sucesso."
                });
            }
            catch (Exception ex)
            {
                return Json(JsonResultModel<T>.SendDataReturn(null, true, ex.Message));
            }
        }

        public virtual ActionResult File(dynamic image)
        {
            return Json(new JsonResult());
        }
        protected abstract T LoadReferences(T model);
    }
    
}